package com.tanhua.manage.service;


import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanhua.manage.domain.Admin;
import com.tanhua.manage.exception.BusinessException;
import com.tanhua.manage.mapper.AdminMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@Service
public class AdminService extends ServiceImpl<AdminMapper, Admin> {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private AdminMapper adminMapper;

    @Value("${tanhua.secret}")
    private String secret;

    /**
     * 接口名称：用户登录验证码图片
     */
    public void saveCap(String uuid, String code) {
        // 1.拼接验证码redis中的key
        String key = "MANAGE_CAP_" + uuid;

        // 2.存储验证码到redis中，并设置过期时间为2分钟
        redisTemplate.opsForValue().set(key, code, Duration.ofMinutes(2));
    }

    /**
     * 接口名称：用户登录
     */
    public ResponseEntity<Object> login(Map<String, String> param) {
        // 1.获取参数内容
        String username = param.get("username");
        String password = param.get("password");
        String verificationCode = param.get("verificationCode");
        String uuid = param.get("uuid");

        // 2.校验用户名、密码
        // 2.1 校验是否为空
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            throw new BusinessException("用户名或密码为空！");
        }
        // 2.2 判断用户是否存在
        Admin admin = query().eq("username", username).one();
        if (admin == null) {
            throw new BusinessException("用户不存在！");
        }

        // 2.3 判断密码是否正确
        if (!admin.getPassword().equals(SecureUtil.md5(password))) {
            throw new BusinessException("用户名或密码错误！");
        }

        // 3.校验验证码
        String key = "MANAGE_CAP_" + uuid;
        String redisCode = redisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(verificationCode) || StringUtils.isEmpty(redisCode)
                || !redisCode.equals(verificationCode)) {
            throw new BusinessException("校验验证码失败！");
        }

        // 4.删除验证码
        redisTemplate.delete(key);

        // 5.生成token
        // 定义要加密的数据
        Map<String, Object> map = new HashMap<>();
        map.put("id", admin.getId());
        map.put("username", admin.getUsername());

        String token = Jwts.builder()
                .setClaims(map) // 声明加密的数据
                .signWith(SignatureAlgorithm.HS256, secret) // 指定加密算法与密钥
                .compact();

        // 6.将token存入redis
        redisTemplate.opsForValue().set("MANAGE_TOKEN_" + token, JSON.toJSONString(admin), Duration.ofHours(4));

        // 7.定义返回结果
        Map<String, String> result = new HashMap<>();
        result.put("token", token);

        return ResponseEntity.ok(result);
    }

    // 根据登录token，获取用户对象
    public Admin findUserByToken(String token) {
        String userStr = redisTemplate.opsForValue().get("MANAGE_TOKEN_" + token);
        if (userStr == null) {
            return null;
        }
        // 续期
        redisTemplate.opsForValue().set("MANAGE_TOKEN_" + token, userStr, Duration.ofHours(4));
        return JSON.parseObject(userStr, Admin.class);
    }

    /**
     * 接口名称：用户登出
     */
    public ResponseEntity<Object> logout(String token) {
        String key = "MANAGE_TOKEN_" + token;
        redisTemplate.delete(key);
        return ResponseEntity.ok(null);
    }
}
